package com.ug.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ug.common.constant.CommonConstants;
import com.ug.common.enums.ErrorCode;
import com.ug.common.exception.SystemException;
import com.ug.common.id.SnowFlakeFactory;
import com.ug.common.utils.JwtUtil;
import com.ug.common.utils.StringUtil;
import com.ug.system.entity.SysRole;
import com.ug.system.entity.SysUser;
import com.ug.system.entity.dto.QueryDto;
import com.ug.system.entity.dto.SysUserDto;
import com.ug.system.entity.vo.SysUserExportVO;
import com.ug.system.entity.vo.SysUserVO;
import com.ug.system.entity.dto.PasswordDto;
import com.ug.system.mapper.SysUserMapper;
import com.ug.system.service.SysRoleService;
import com.ug.system.service.SysRoleUserService;
import com.ug.system.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @Author LY
 * @create 2024/7/16 15:50
 * @Description 用户服务实现层
 */
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final PasswordEncoder passwordEncoder;

    private final SysRoleUserService roleUserService;

    private final SysRoleService roleService;

    @Override
    public SysUser findByUserId(Long userId) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUserId, userId);
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public SysUser findByName(String userName) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, userName);
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public SysUser findByOpenId(String openId) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getOpenId, openId);
        return baseMapper.selectOne(wrapper);
    }

    @Override
    public void editUser(SysUserVO sysUserVO) {
        checkUser(sysUserVO);
        SysUser user = new SysUser();
        user.setPassword(sysUserVO.getPassword());
        user.setUsername(sysUserVO.getUsername());
        user.setEmail(sysUserVO.getEmail());
        user.setUserId(sysUserVO.getUserId());
        user.setNickName(sysUserVO.getNickName());
        user.setPhoneNumber(sysUserVO.getPhoneNumber());
        if (user.getUserId() != null){
            baseMapper.updateById(user);
        } else {
            user.setUserId(SnowFlakeFactory.getSnowFlakeFromCache().nextId());
            user.setEnabled(1);// 默认启用
            //  初始化用户密码.默认111111
            user.setPassword(passwordEncoder.encode(CommonConstants.DEFAULT_PASSWORD));
            user.setRegisterType(CommonConstants.LOGIN_TYPE_ACCOUNT);
            baseMapper.insert(user);
        }

        //  如果带有角色,就修改角色
        if (!CollectionUtils.isEmpty(sysUserVO.getRoleIds()) && user.getUserId() != null){
            roleUserService.edit(user.getUserId(), sysUserVO.getRoleIds());
        }
    }

    @Override
    public void saveUserByFirst(SysUser sysUser) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getOpenId, sysUser.getOpenId());
        Long count = baseMapper.selectCount(wrapper);
        if (count > 0) return;
        sysUser.setUserId(SnowFlakeFactory.getSnowFlakeFromCache().nextId());
        sysUser.setEnabled(1);// 默认启用
        baseMapper.insert(sysUser);
        // 添加默认角色，默认管理员
        SysRole role = roleService.getRoleByCode(CommonConstants.ROLE_ADMIN);
        roleUserService.edit(sysUser.getUserId(), List.of(String.valueOf(role.getRoleId())));
    }

    @Override
    public IPage<SysUserVO> queryUserTable(SysUserDto sysUserDto, QueryDto queryDto) {
        Page<SysUserVO> page = new Page<>();
        page.setCurrent(queryDto.getCurrentPage());
        page.setSize(queryDto.getSize());
        return baseMapper.queryUserTable(page, sysUserDto);
    }

    @Override
    public SysUserVO loadByName(String username) {
        return baseMapper.loadByName(username);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delUser(String userId) {
        //  先解除用户与角色的绑定
        roleUserService.deleteByUserId(userId);
        //  再删除用户
        baseMapper.deleteById(userId);
    }

    @Override
    public void enabledUser(Long userId, int enabled) {
        SysUser user = new SysUser();
        user.setUserId(userId);
        user.setEnabled(enabled);
        baseMapper.updateById(user);
    }

    @Override
    public void updatePassword(PasswordDto passwordVo) {
        String password = passwordVo.getPassword();
        String newPassword = passwordVo.getNewPassword();
        String confirmPassword = passwordVo.getConfirmPassword();

        //  获取当前登录用户
        SysUser user = baseMapper.selectById(JwtUtil.getUserId());
        String pwd = user.getPassword();
        //  校验原密码
        if (!passwordEncoder.matches(password, pwd)){
            throw new SystemException(ErrorCode.INI_PASSWORD_ERROR);
        }
        //  校验新密码与确认密码
        if (!newPassword.equals(confirmPassword)){
            throw new SystemException(ErrorCode.NEW_PASSWORD_ERROR);
        }
        //  修改密码为新密码
        user.setPassword(passwordEncoder.encode(newPassword));
        baseMapper.updateById(user);
    }

    @Override
    public void saveAccount(String username, String password) {
        checkAccount(username);
        SysUser user = new SysUser();
        user.setUserId(JwtUtil.getUserId());
        user.setUsername(username);
        user.setPassword(passwordEncoder.encode(password));
        baseMapper.updateById(user);
    }

    @Override
    public void updateSysUser(SysUserDto sysUserDto) {
        if (StrUtil.isEmpty(sysUserDto.getNickName())
                || StrUtil.isEmpty(sysUserDto.getEmail())
                || StrUtil.isEmpty(sysUserDto.getPhoneNumber())) {
            throw new SystemException(ErrorCode.PARAMS_INVALID);
        }
        SysUser user = new SysUser();
        user.setUserId(JwtUtil.getUserId());
        user.setEmail(sysUserDto.getEmail());
        user.setNickName(sysUserDto.getNickName());
        user.setPhoneNumber(sysUserDto.getPhoneNumber());
        baseMapper.updateById(user);
    }

    @Override
    public List<SysUserExportVO> exportList(SysUserDto dto) {
        return baseMapper.exportList(dto);
    }

    /**
     * 校验用户名和昵称
     * @param userDto 用户dto
     */
    private void checkUser(SysUserVO userDto){
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();

        if (userDto.getUserId() != null){
            wrapper.ne(SysUser::getUserId, userDto.getUserId());
        }
        if (StringUtil.isNotBlank(userDto.getUsername()) && StringUtil.isNotBlank(userDto.getNickName())){
            wrapper.and(w -> w.eq(SysUser::getUsername, userDto.getUsername()).or().eq(SysUser::getNickName, userDto.getNickName()));
        }
        long count = baseMapper.selectCount(wrapper);
        if (count > 0){
            throw new SystemException(ErrorCode.USERNAME_OR_NICKNAME_ERROR);
        }
    }

    /**
     * 根据用户名校验是否已经存在
     */
    private void checkAccount(String username){
        if (StrUtil.isEmpty(username)){
            throw new SystemException(ErrorCode.USERNAME_IS_NULL);
        }
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, username);
        long count = baseMapper.selectCount(wrapper);
        if (count > 0){
            throw new SystemException(ErrorCode.USERNAME_OR_NICKNAME_ERROR);
        }
    }
}
